package jehc.djshi.omp.util;

import cn.hutool.core.collection.CollectionUtil;
import jehc.djshi.common.util.JsonUtil;
import jehc.djshi.common.util.StringUtil;
import jehc.djshi.omp.model.OMPRedisConfig;
import jehc.djshi.omp.model.OMPRedisInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
 * @Desc Redis配置
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Component
@Slf4j
public class JedisUtil {

    private static Map<String,JedisPool> jedisPoolMap = new ConcurrentHashMap<>();

    /**
     *
     * @param redisConfig
     * @return
     */
    public Jedis getJedis(OMPRedisConfig redisConfig){
        if(null == redisConfig){
            log.warn("redis连接配置为空");
            return null;
        }
        if(StringUtil.isEmpty(redisConfig.getHost())){
            log.warn("redis ip为空");
            return null;
        }
        if(null == redisConfig.getPort()){
            log.warn("redis 端口为空");
            return null;
        }
        Jedis jedis = new Jedis (redisConfig.getHost(),redisConfig.getPort());
        if(!StringUtil.isEmpty(redisConfig.getPassword())){
            jedis.auth(redisConfig.getPassword());
        }
        return jedis;
    }

    /**
     * 释放jedis资源
     * @param jedis
     */
    public void closeJedis(Jedis jedis) {
        if(null != jedis){
            try {
                jedis.close();
            }catch (Exception e){
                log.error("释放Redis连接池异常：{}-{}",e,jedis);
            }
        }
    }

    /**
     * 初始化所有连接池至Hash中
     * @param redisConfig
     */
    public void initJedisPoolMap(OMPRedisConfig redisConfig){
        if(null == redisConfig){
            log.warn("redis连接配置为空");
            return;
        }
        if(StringUtil.isEmpty(redisConfig.getHost())){
            log.warn("redis ip为空");
            return;
        }
        if(null == redisConfig.getPort()){
            log.warn("redis 端口为空");
            return;
        }
        if(CollectionUtil.isEmpty(jedisPoolMap)){
            jedisPoolMap = new ConcurrentHashMap<>();
        }
        JedisPool jedisPool = initJedisPool(redisConfig);
        if(null != jedisPool){
            jedisPoolMap.put(redisConfig.getHost()+redisConfig.getPort(),jedisPool);
        }
    }

    /**
     *
     * @param redisConfig
     * @return
     */
    public JedisPool initJedisPool(OMPRedisConfig redisConfig){
        try {
            if(null == redisConfig){
                log.warn("redis连接配置为空");
                return null;
            }
            if(StringUtil.isEmpty(redisConfig.getHost())){
                log.warn("redis ip为空");
                return null;
            }
            if(null == redisConfig.getPort()){
                log.warn("redis 端口为空");
                return null;
            }
            JedisPool jedisPool = jedisPoolMap.get(redisConfig.getHost()+redisConfig.getPort());
            if (jedisPool == null) {
                JedisPoolConfig config = new JedisPoolConfig();
                config.setMaxTotal(redisConfig.getMaxTotal());
                config.setMaxIdle(redisConfig.getMaxIdle());
                config.setMaxWaitMillis(redisConfig.getMaxWaitMillis());
                config.setTestWhileIdle(true);
                config.setNumTestsPerEvictionRun(1024);//每次释放连接的最大数目,默认3
                config.setMinEvictableIdleTimeMillis(300000);//连接的最小空闲时间 默认1800000毫秒(30分钟)
                config.setTimeBetweenEvictionRunsMillis(30000);//逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
                config.setTestOnBorrow(redisConfig.getTestOnBorrow());
                if(StringUtil.isEmpty(redisConfig.getPassword())){
                    jedisPool = new JedisPool(config, redisConfig.getHost(), redisConfig.getPort(), redisConfig.getTimeout());
                }else{
                    jedisPool = new JedisPool(config, redisConfig.getHost(), redisConfig.getPort(), redisConfig.getTimeout(), redisConfig.getPassword());
                }
                return jedisPool;
            } else {
                return null;
            }

        }catch (Exception e){
            log.error("初始化JedisPool异常,异常信息：{}-{}",e,redisConfig);
            return null;
        }
    }

    /**
     * 获取连接池中Jedis实例
     * @return
     */
    public Jedis getPoolJedis(OMPRedisConfig redisConfig) {
        try {
            if(null == redisConfig){
                log.warn("redis连接配置为空");
                return null;
            }
            if(StringUtil.isEmpty(redisConfig.getHost())){
                log.warn("redis ip为空");
                return null;
            }
            if(null == redisConfig.getPort()){
                log.warn("redis 端口为空");
                return null;
            }
            if(CollectionUtil.isEmpty(jedisPoolMap)){
                initJedisPoolMap(redisConfig);
            }
            JedisPool jedisPool = jedisPoolMap.get(redisConfig.getHost()+redisConfig.getPort());
            if (jedisPool != null) {
                Jedis jedis = jedisPool.getResource();
                log.info("当前活跃连接：" + jedis + ",activeNum:"+ jedisPool.getNumActive() + ",idleNum:" + jedisPool.getNumIdle() + ",waiterNum:" + jedisPool.getNumWaiters());
                return jedis;
            } else {
                return null;
            }
        } catch (Exception e) {
            log.error("获取Jedis异常：{}-{}",e,redisConfig);
            return null;
        }
    }

    /**
     * 释放jedis资源
     * @param jedis
     */
    public void closePoolJedis(Jedis jedis) {
        if(null == jedis){
            log.warn("jedis不存在");
            return;
        }
        if(null != jedis){
            try {
                jedis.close();
            }catch (Exception e){
                log.error("释放Redis连接池异常：{}-{}",e,jedis);
            }
        }
    }

    /**
     * 释放jedis pool连接池
     * @param redisConfig
     */
    public void closeRedisPool(OMPRedisConfig redisConfig) {
        if(null == redisConfig){
            log.warn("redis连接配置为空");
            return;
        }
        if(StringUtil.isEmpty(redisConfig.getHost())){
            log.warn("redis ip为空");
            return;
        }
        if(null == redisConfig.getPort()){
            log.warn("redis 端口为空");
            return;
        }
        if(CollectionUtil.isEmpty(jedisPoolMap)){
            return;
        }
        JedisPool jedisPool = jedisPoolMap.get(redisConfig.getHost()+redisConfig.getPort());
        if (jedisPool != null) {
            try {
                jedisPool.close();
                jedisPool.destroy();
                jedisPoolMap.remove(redisConfig.getHost()+redisConfig.getPort());
            }catch (Exception e){
                log.error("释放Redis连接池异常：{}-{}",e,redisConfig);
            }
        }
    }

    /**
     *
     * @param info
     * @return
     */
    public OMPRedisInfo convertInfo(String info){
        if(StringUtil.isEmpty(info)){
            return null;
        }
        Map<String,Object> map = new HashMap<>();
        String[] infos = info.split("\r\n");
        if(null != infos && infos.length>0){
            for(String str:infos){
                String[] strings = str.split(":");
                if(null != strings && strings.length>1){
                    map.put(strings[0],strings[1]);
                }
            }
        }
        OMPRedisInfo redisInfo = new OMPRedisInfo();
        if(!CollectionUtil.isEmpty(map)){
            redisInfo = JsonUtil.fromFastJson(map,OMPRedisInfo.class);
        }
        return redisInfo;
    }
}
